<?php

namespace Console\Supports;

use Console\Supports\Helper;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class DatabaseSeeder extends Command
{

    protected static $defaultName = 'db:seed';

    protected function configure()
    {
        $this->setDescription('运行数据填充')
            ->addOption('class', '', InputArgument::OPTIONAL, '数据填充类');
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        $seederClassName = $input->getOption('class');

        $seedersRs = $this->getSeederFile();

        if (isset($seederClassName)) {
            $isExist = false;
            $tmp = str_replace(ROOT_PATH, '', Helper::seederFileBasePath());
            $tmp = 'C' . substr($tmp, 1);
            $tmp = str_replace('/', '\\', $tmp) . '\\';
            foreach ($seedersRs as $v) {
                $v = str_replace($tmp, '', $v);
                if ($v == $seederClassName) {
                    $isExist = true;
                    break;
                }
            }
            if ($isExist === false) {
                $output->writeln('<error>指定数据填充类不存在</>');
                return 1;
            }

            $this->runSeeder($tmp . $seederClassName, $output);
        } else {
            foreach ($seedersRs as $v) {
                $this->runSeeder($v, $output);
            }
        }

        return 0;
    }

    /**
     * 获取待执行的填充文件列表
     */
    private function getSeederFile($path = ''): array
    {
        if ($path == '') {
            $path = Helper::seederFileBasePath();
        }

        $fileRs = scandir($path);
        $result = array();
        foreach ($fileRs as $v) {
            if ($v == '.' || $v == '..') {
                continue;
            }
            $v = $path . DIRECTORY_SEPARATOR . $v;
            if (is_dir($v)) {
                $result = array_merge($result, $this->getSeederFile($v));
            } else {
                $extension = strtolower(pathinfo($v, PATHINFO_EXTENSION));
                if ($extension !== 'php') {
                    continue;
                }

                $class = str_replace(ROOT_PATH . 'console', 'Console', $v);
                $class = str_replace('.php', '', $class);
                $result[] = str_replace('/', '\\', $class);
            }
        }
        return $result;
    }

    /**
     * 执行数据填充
     */
    private function runSeeder(string $className, OutputInterface $output)
    {
        $output->write('<comment>Seeding:</comment>');
        $output->write($className . PHP_EOL);
        $start = microtime(true);

        if (class_exists($className) === false) {
            throw new Exception('不存在');
        }
        $classMethod = get_class_methods($className);
        if (!is_array($classMethod) || !in_array('run', $classMethod)) {
            throw new Exception('不存在run方法');
        }

        $seeder = new $className;
        $seeder->run();

        $output->write('<info>Seeded:</info> ');
        $runTime = microtime(true);
        $runTime = $runTime - $start;
        $runTime = bcmul($runTime, 1000, 3);
        $output->write($className . "\t(" . $runTime . 'ms)' . PHP_EOL);
    }
}
